/**
 * 
 */
package com.oron3.bouncer.objects.shapes;

import java.util.ArrayList;

/**
 * @author Ofek
 *
 */
public class Arc implements Shape {

	public static final int RELATION_ON= 0;
	public static final int RELATION_OUTSIDE = 1;
	public static final int RELATION_INSIDE = 2;
	public static final int RELATION_PART_IN_PART_OUT = 3;

	public final ArrayList<Rectangle> recs = new ArrayList<Rectangle>();
	public Point center;

	/**
	 * 
	 */
	public Arc() {}

	public Arc(final Point leftBottom, final float lx, final float ly, final float lz) {
		center = leftBottom.add(lx / 2, ly / 2, lz / 2);
		recs.add(new Rectangle(leftBottom.add(0, 0, lz), leftBottom, leftBottom.add(lx, 0, 0)));
		recs.add(new Rectangle(leftBottom.add(lx, 0, 0), leftBottom, leftBottom.add(0, ly, 0)));
		recs.add(new Rectangle(leftBottom.add(0, ly, 0), leftBottom, leftBottom.add(0, 0, lz)));

		recs.add(new Rectangle(leftBottom.add(lx, 0, 0), leftBottom.add(lx, ly, 0), leftBottom.add(lx, ly, lz)));
		recs.add(new Rectangle(leftBottom.add(lx, ly, lz), leftBottom.add(lx, ly, 0), leftBottom.add(0, ly, 0)));
		recs.add(new Rectangle(leftBottom.add(0, ly, lz), leftBottom.add(0, 0, lz), leftBottom.add(lx, 0, lz)));
	}



	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oron3.bouncer.objects.shapes.Shape#intersects(com.oron3.bouncer.objects.shapes.Shape)
	 */
	@Override
	public boolean intersects(final Shape o) {

		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oron3.bouncer.objects.shapes.Shape#intersection(com.oron3.bouncer.objects.shapes.Shape)
	 */
	@Override
	public Intersection intersection(final Shape o) {

		if (o instanceof Line) {
			final Intersection intersection = new Intersection();
			for (final Rectangle r : recs) {
				final Intersection i = r.intersection(o);
				if (i != null) intersection.shapes.add(i.shapes.get(0));
			}
			return intersection;
		}
		else throw new IllegalArgumentException();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oron3.bouncer.objects.shapes.Shape#calcRelation(com.oron3.bouncer.objects.shapes.Shape)
	 */
	@Override
	public int describeRelation(final Shape o) {
		if (o instanceof Point) {
			boolean insideEntirely = true;
			for (final Rectangle rec : recs) {
				final int calcRelation = rec.describeRelation(o);
				if ( calcRelation==Rectangle.RELATION_OVERLAP_INSIDE_BOUNDS ) return RELATION_ON;
				insideEntirely &= calcRelation == Rectangle.RELATION_OVERLAP_INSIDE_BOUNDS || calcRelation==Rectangle.RELATION_NOT_OVERLAP_INSIDE_BOUNDS_IN_NORAML_DIRECTION;
			}
			if ( insideEntirely ) return RELATION_INSIDE;
			return RELATION_OUTSIDE;
		}
		throw new IllegalArgumentException();
	}

	/**
	 * @param center
	 * @return
	 */
	public Point closestPoint(final Point point) {
		final Line line = new Line(center, point);
		final Intersection intersection = intersection(line);
		return ShapeUtils.closestPoint(point, (Point) intersection.shapes.get(0), (Point) intersection.shapes.get(1));
	}

	/* (non-Javadoc)
	 * @see com.oron3.bouncer.objects.shapes.Shape#isInside(com.oron3.bouncer.objects.shapes.Shape)
	 */
	@Override
	public boolean isInside(final Shape o) {
		final int describeRelation = describeRelation(o);
		return describeRelation==RELATION_INSIDE || describeRelation==RELATION_ON;
	}

	/* (non-Javadoc)
	 * @see com.oron3.bouncer.objects.shapes.Shape#project(com.oron3.bouncer.objects.shapes.Shape)
	 */
	@Override
	public Shape project(final Shape o) {
		throw new IllegalArgumentException();
	}
}
